package com.apestech.framework.util;

import java.net.SocketException;
import java.net.UnknownHostException;
import java.sql.Connection;
import java.util.Hashtable;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidPooledConnection;
import com.apestech.formwork.stream.ListStream;
import com.apestech.framework.db.SqlSession;
import com.apestech.framework.util.modul.DBInfo;
import com.apestech.framework.util.modul.DBList;
import org.flowable.engine.*;

public class DBUtil extends StringUtil{

	private static DBList SYS_DB=new DBList();
	private static Hashtable<String, DruidPooledConnection> SYS_CONN=new Hashtable<String, DruidPooledConnection>();
	private static Hashtable<String, ListStream> SYS_DICT=new Hashtable<String, ListStream>();
	private static Hashtable<String, String> SYS=new Hashtable<String, String>();
	private static Sys.SysInfo sysInfo=null;
	private static String SYS_DB_ID=null;
	private static boolean dbreadonly=false;

	public static String addDataSource(DruidDataSource dataSource) throws Exception {
		getSys();
		return SYS_DB.add(dataSource);
	}

	public static String addDataSource(DruidDataSource dataSource, String db) throws Exception {
		getSys();
		return SYS_DB.add(dataSource, db);
	}

	public static DBInfo getDBInfo(DruidDataSource dataSource) throws Exception {
		getSys();
		return SYS_DB.getDBInfo(dataSource);
	}

	public static DruidDataSource getDataSource(String db) throws Exception{
		getSys();
		return SYS_DB.getDataSource(db);
	}

	public static Connection getOpenConntection(String db) throws Exception{
		if(SYS_CONN.get(db)==null){
			DruidDataSource ds=getDataSource(db);
			SYS_CONN.put(db, ds.getConnection());
		}
		return SYS_CONN.get(db);
	}
	
	public static int getActiveCount(String db) throws Exception{
		DruidDataSource ds=getDataSource(db);
		return ds.getActiveCount();
	}
	
	public static ListStream getDictionaryDate(String fileName, String type) throws Exception{
		ListStream list=null;
		if(SYS_DICT.get(type)==null){
			list=new ListStream(FileUtil.getFileNameForSys(fileName+"\\"+type));
			SYS_DICT.put(type, list);
		} else {
			list=SYS_DICT.get(type);
			if(list.getFileName().equals(fileName)) return list;
			else return new ListStream(FileUtil.getFileNameForSys(fileName+"\\"+type));
		}
		return list;
	}

	public static SqlSession getSession(String db) throws Exception {
		DBInfo info=SYS_DB.getDBInfo(db);
		SqlSession session=new SqlSession(info);
		String t=db;
		int pos=t.indexOf(".");
		if(pos>=0) t=db.substring(pos+1, db.length());
		session.setTheme(t);
		return session;
	}

	public static SqlSession getSession(DruidDataSource dataSource) throws Exception {
		String db=addDataSource(dataSource);
		return getSession(db);
	}

	public static SqlSession getSession() throws Exception {
		if(SYS_DB.size()!=1){
			throw new Exception("当前数据库不止一个，请检查代码逻辑并调整数据库入口设定思路！");
		}
		return getSession(SYS_DB.getSingleDBName());
	}

	public static ProcessEngine getProcessEngine(String db) throws Exception {
		return SYS_DB.getEngine(db);
	}

	public static void setSysSingleDB(String sysid, String db){
		SYS.put(sysid, db);
		SYS_DB_ID=sysid;
	}

	public static String getSysSingleSysId(){
		return SYS_DB_ID;
	}

	public static String getSysSingleDBName(String sysid){
		return SYS.get(sysid);
	}

	public static Sys.SysInfo getSysInfo() throws Exception {
		if(sysInfo==null) getSys();
		return sysInfo;
	}

	public static void getSys() throws Exception {
		if(sysInfo==null){
			Sys sys=new Sys();
			try {
				sys.getConfig();
				sysInfo=sys.getSysInfo();
			} catch (SocketException e) {
				throw new Exception(e);
			} catch (UnknownHostException e) {
				throw new Exception(e.getMessage());
			}
		}
	}

	public static boolean isDbreadonly() {
		return dbreadonly;
	}

	public static void setDbreadonly(boolean dbreadonly) {
		DBUtil.dbreadonly = dbreadonly;
	}
}
